//Copyright 2012 Trevin Liberty
//GNU GPL v3
//Author: Trevin Liberty

#include "../Archer.h"
#include "ArcherOwnedStates.h"
#include "StateFunctions.h"

#include <iostream>
using std::cout;
using std::endl;

//------------------------------------------------------------------------
//
//		WaitA
//
//------------------------------------------------------------------------

WaitA* WaitA::Instance() {
	static WaitA instance;

	return &instance;
}

void WaitA::Enter(Archer* archer) {
	cout << "ENTER WaitA" << endl;
	moveEntityMapCell(archer, archer->getPosIndex());
}

void WaitA::Execute(Archer* archer) {
	//cout << "EXECUTE WaitA" << endl;
	if(!archer->getPath()->empty())
		archer->getStateMachine()->ChangeState(MoveA::Instance());
	else if(archer->hasTarget())
		archer->getStateMachine()->ChangeState(AttackA::Instance());
	else
		archer->setTarget(someEnemyInRange(archer, archer->getAttackRange()));
}

void WaitA::Exit(Archer* archer) {
	cout << "EXIT WaitA" << endl;
}

//------------------------------------------------------------------------
//
//		MoveA
//
//------------------------------------------------------------------------

MoveA* MoveA::Instance() {
	static MoveA instance;

	return &instance;
}

void MoveA::Enter(Archer* archer) {
	cout << "ENTER MoveA" << endl;
	//if no path
	if(archer->getPath()->empty())
		archer->getStateMachine()->ChangeState(WaitA::Instance());
	
	archer->setCurrentDestination(archer->getPath()->front());
	archer->getPath()->pop_front();
}

void MoveA::Execute(Archer* archer) {
	//cout << "EXECUTE MoveA" << endl;
	//If no path
	if(archer->getPath()->empty() && archer->hasArrived()) {
		archer->getStateMachine()->ChangeState(WaitA::Instance());
		return;
	}

	moveUnit(archer);

	if(archer->hasTarget()) {
		if(archer->inRangeOfTarget() && archer->hasArrived()) {
			archer->getStateMachine()->ChangeState(AttackA::Instance());
			return;
		}
	}
}

void MoveA::Exit(Archer* archer) {
	cout << "EXIT MoveA" << endl;
}

//------------------------------------------------------------------------
//
//		AttackA
//
//------------------------------------------------------------------------

AttackA* AttackA::Instance() {
	static AttackA instance;

	return &instance;
}

void AttackA::Enter(Archer* archer) {
	cout << "ENTER AttackA" << endl;
}

void AttackA::Execute(Archer* archer) {
	if(!archer->hasTarget()) {
		archer->getStateMachine()->ChangeState(WaitA::Instance());
		return;
	}

	if(!archer->inRangeOfTarget()) {
		archer->setTarget(NULL);
		archer->getStateMachine()->ChangeState(WaitA::Instance());
		return;
	}

	if(al_get_time() - archer->getLastAttackTime() > archer->getAttackSpeed() - .3 &&
		archer->getCurrentImageNum() == 8) {
		Doohickey* e = archer->getTarget();
		archer->shootArrow(e->getPosition());
		archer->setLastAttackTime();
	}
}

void AttackA::Exit(Archer* archer) {
	cout << "EXIT AttackA" << endl;
}